package com.panopset.sf;

import java.awt.Color;
import java.awt.LayoutManager;

import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.text.JTextComponent;

import com.deprecated.patch.LookAndFeel;

/**
 * Swing component factory.
 *
 * @author Karl Dinwiddie.
 *
 */
public final class ComponentFactory {

    private FontManager fm = FontManager.getInstance();

    /**
     * @param layout
     *            Layout.
     * @return Panel with a white background.
     */
    public JPanel createPanel(final LayoutManager layout) {
        JPanel p = new JPanel(layout);
        p.setBackground(Color.WHITE);
        return p;
    }

    /**
     * @param layout
     *            Layout.
     * @param title
     *            Title.
     * @param tip
     *            Tool tip text.
     * @return Panel with a white background.
     */
    public JPanel createTitledPanel(final LayoutManager layout,
            final String title, final String tip) {
        JPanel p = createTitledPanel(layout, title);
        p.setToolTipText(tip);
        return p;
    }

    /**
     * @param layout
     *            Layout.
     * @param title
     *            Title.
     * @return Panel with a white background.
     */
    public JPanel createTitledPanel(final LayoutManager layout,
            final String title) {
        JPanel p = createPanel(layout);
        p.setBorder(createTitledBorder(title));
        return p;
    }

    /**
     * @param w
     *            Windoc.
     * @param columns
     *            Field width.
     * @param tip
     *            Tool tip text.
     * @param dft
     *            Default.
     * @param key
     *            Persistent store key. If the key is empty, a key will be
     *            generated based on the stack trace. If the key is null, there
     *            will be no registration.
     * @return Text field.
     */
    public JTextField createTextField(final Windoc w, final int columns,
            final String tip, final String dft, final String key) {
        final JTextField tf = createTextField(w, dft, key);
        tf.setColumns(columns);
        tf.setToolTipText(tip);
        return tf;
    }

    /**
     * @param w
     *            Windoc.
     * @param dft
     *            Default.
     * @param key
     *            Persistent store key. If the key is empty, a key will be
     *            generated based on the stack trace. If the key is null, there
     *            will be no registration.
     * @return Text field.
     */
    public JTextField createTextField(final Windoc w, final String dft,

    final String key) {
        final JTextField tf = new JTextField();
        registerTextComponent(w, tf, dft, key);
        return tf;
    }

    /**
     * @param w
     *            Windoc.
     * @param key
     *            Persistent store key. If the key is empty, a key will be
     *            generated based on the stack trace. If the key is null, there
     *            will be no registration.
     * @return Text field.
     */
    public JTextField createKeyedTextField(final Windoc w,
            final String key) {
        return createTextField(w, "", key);
    }

    /**
     *
     * @return Tabbed pane.
     */
    public JTabbedPane createTabbedPane() {
        JTabbedPane jtp = new JTabbedPane();
        fm.register(jtp, FontManager.FontType.plainArial);
        jtp.setBackground(Color.WHITE);
        return jtp;
    }

    /**
     * @param w
     *            Windoc
     * @param c
     *            Component.
     * @param dft
     *            Default value.
     * @param key
     *            Storage key. Can be null, for fields that are not persistent.
     * @return c Component.
     */
    public JTextComponent registerTextComponent(final Windoc w,
            final JTextComponent c, final String dft, final String key) {
        if (w != null & key != null) {
            w.registerGrounding(new Grounding() {

                @Override
                public void setValue(final String value) {
                    c.setText(value);
                }

                @Override
                public String getValue() {
                    return c.getText();
                }
            }, dft, key);
        }
        fm.register(c, FontManager.FontType.monospace);
        c.setBackground(Color.WHITE);
        return c;
    }

    /**
     * @param title
     *            Title.
     * @return Titled border.
     */
    public TitledBorder createTitledBorder(final String title) {
        TitledBorder tb = new TitledBorder(title);
        fm.register(tb, FontManager.FontType.borderTitle);
        tb.setTitleColor(LookAndFeel.Colors.FG_COLOR.getColor());
        return tb;
    }

    /**
     * @param w
     *            Windoc
     * @param columns
     *            Field width.
     * @param title
     *            Title.
     * @param tip
     *            Tool tip text.
     * @param dft
     *            Default.
     * @param key
     *            Persistent store key. If the key is empty, a key will be
     *            generated based on the stack trace. If the key is null, there
     *            will be no registration.
     * @return Field with a titled border.
     */
    public JTextField createTitledField(final Windoc w,
            final int columns, final String title, final String tip,
            final String dft, final String key) {
        JTextField rtn = createTextField(w, dft, key);
        rtn.setColumns(columns);
        rtn.setBorder(createTitledBorder(title));
        rtn.setToolTipText(tip);
        return rtn;
    }

    /**
     * @param w
     *            Windoc.
     * @param columns
     *            Field width.
     * @param title
     *            Title.
     * @param tip
     *            Tool tip text.
     * @param key
     *            Persistent store key. If the key is empty, a key will be
     *            generated based on the stack trace. If the key is null, there
     *            will be no registration.
     * @return Field with a titled border.
     */
    public JTextField createTitledField(final Windoc w,
            final int columns, final String title, final String tip,
            final String key) {
        return createTitledField(w, columns, title, tip, "", key);
    }

    /**
     * @param w
     *            Windoc.
     * @param title
     *            Title.
     * @param tip
     *            Tool tip text. Can be null.
     * @param dft
     *            Default.
     * @param key
     *            Persistent store key. If the key is empty, a key will be
     *            generated based on the stack trace. If the key is null, there
     *            will be no registration.
     * @return Text area with a titled border.
     */
    public TitledTextArea createTitledTextArea(final Windoc w,
            final String title,

            final String tip, final String dft, final String key) {
        return new TitledTextArea(w, title, tip, dft, key);
    }

    /**
     * @param w
     *            Windoc.
     * @param title
     *            Title.
     * @param tip
     *            Tool tip text. Can be null.
     * @param key
     *            Persistent store key. If the key is empty, a key will be
     *            generated based on the stack trace. If the key is null, there
     *            will be no registration.
     * @return Text area with a titled border.
     */
    public TitledTextArea createTitledTextArea(final Windoc w,
            final String title,

            final String tip, final String key) {
        return new TitledTextArea(w, title, tip, key);
    }

    /**
     * @param w
     *            Windoc.
     * @param columns
     *            Columns.
     * @param tip
     *            Tool tip text.
     * @param dft
     *            Default.
     * @param key
     *            Persistent store key. If the key is empty, a key will be
     *            generated based on the stack trace. If the key is null, there
     *            will be no registration.
     * @return Password field
     */
    public JPasswordField createPasswordField(final Windoc w,
            final int columns, final String tip, final String dft,
            final String key) {
        JPasswordField jpf = new JPasswordField();
        jpf.setToolTipText(tip);
        registerTextComponent(w, jpf, dft, key);
        return jpf;
    }

    /**
     * @param w
     *            Windoc.
     * @param columns
     *            Columns.
     * @param title
     *            Title.
     * @param tip
     *            Tool tip text.
     *
     * @param key
     *            Persistent store key. If the key is empty, a key will be
     *            generated based on the stack trace. If the key is null, there
     *            will be no registration.
     * @return Password field.
     */
    public JPasswordField createTitledPasswordField(final Windoc w,
            final int columns, final String title, final String tip,
            final String key) {
        JPasswordField jpf = createPasswordField(w, columns, tip, "", key);
        jpf.setBorder(createTitledBorder(title));
        return jpf;
    }

    /**
     * A passive component is a button or menu that does not need to save state.
     *
     * @param c
     *            JComponent to register with FontManager and set to theme
     *            colors.
     */
    public void registerPassiveComponent(final JComponent c) {
        fm.register(c, FontManager.FontType.boldArial);
    }

    /**
     * @param w
     *            Windoc.
     * @param name
     *            Name.
     * @param tip
     *            Tip.
     * @param dft
     *            Default value.
     * @param key
     *            Persistent store key. If the key is empty, a key will be
     *            generated based on the stack trace. If the key is null, there
     *            will be no registration.
     * @return JCheckBox that remembers its state.
     */
    public JCheckBox createGroundedCheckBox(final Windoc w,
            final String name,

            final String tip, final boolean dft, final String key) {
        final JCheckBox rtn = new JCheckBox(name);
        rtn.setBackground(Color.WHITE);
        rtn.setToolTipText(tip);
        registerPassiveComponent(rtn);
        w.registerGrounding(new Grounding() {
            @Override
            public void setValue(final String s) {
                rtn.setSelected(Boolean.parseBoolean(s));
            }

            @Override
            public String getValue() {
                return "" + rtn.isSelected();
            }
        }, "" + dft, key);
        return rtn;
    }

    public JComboBox createGroundedCheckBox(final Windoc w, final String name, final String tip,
            final String dft, final String key, final String[] selections) {
        final JComboBox rtn = new JComboBox(selections);
        rtn.setToolTipText(tip);
        rtn.setName(name);
        rtn.setSelectedItem(dft);
        registerPassiveComponent(rtn);
        w.registerGrounding(new Grounding() {
            @Override
            public void setValue(final String s) {
                rtn.setSelectedItem(s);
            }

            @Override
            public String getValue() {
                return rtn.getSelectedItem().toString();
            }
        }, "" + dft, key);
        return rtn;
    }
}
